/**
 * 混合增强xSelects组件
 * 结合formselects-v4-modify(修改增强版)与xmSelect组件，统一封装通用接口
 * author: imlzw
 * url: adai.imlzw.cn
 *
 * 配置项说明：
 * config:{
 *     selectId: 'demo1', // 渲染挂载html元素xm-select Id
 *     disabled: false, // 是否禁用组件
 *     url: '', // 下拉选择列表加载请求地址，
 *     titleKey: '', // 显示标题字段名称
 *     valueKey: '', // 值字段名称
 *     searchKey: '', //  下拉列表搜索参数名称
 *     showPage: true, // 是否显示分页
 *     size: 10, // 分页
 *     initValues: [], // 初始值设置,
 *     multiSelect: true, // 是否多选
 *     tree: {
 *         pidKey: '', // 树形下拉，上级字段值名称
 *         pidFilterParamName: pidKey, // 懒加载时，请求过滤pid参数名,默认等于pidKey
 *         lazy: true, // 懒加载模式
 *         expandedKeys: true, // 展开节点ids，true为展开所有
 *         size: 1000,
 *         strict: false, // 是否严格遵守父子模式
 *         beforeData: function (rs.data){return rs.data} // 数据赋值前的方法处理
 *     },
 *     zIndex: undefined, // 最小层级数
 *     data: [], // 静态数据
 * }
 *
 */
layui.define(['xmSelect', 'formSelects', 'layer'], function (exports) {
        let XSelects = function () {
            this.v = '1.0.0';
            this.renderObj;
            this.renderIns = {};
        }

        /**
         * 渲染组件
         * @param config
         */
        XSelects.prototype.render = function (config) {
            let formSelects = layui.formSelects,
                xmSelect = layui.xmSelect,
                layer = layui.layer;
            $ = layui.$;
            let that = this;
            let renderType = !config.type ? 'formSelects' : config.type;
            if (config.tree) {
                renderType = "xmSelect";
            } else {
                config.tree = {size: 1000}
            }
            config.tree.pidKey = config.tree.pidKey ? config.tree.pidKey : '_pid';
            config.tree.pidFilterParamName = config.tree.pidFilterParamName == undefined ? config.tree.pidKey : config.tree.pidFilterParamName;
            config.tree.size = config.tree.size ? config.tree.size : 1000;
            config.tree.expandedKeys = config.tree.expandedKeys == undefined ? [] : config.tree.expandedKeys;
            config.tree.strict = config.tree.strict == undefined ? false : config.tree.strict;
            config.multiSelect = config.multiSelect == undefined ? true : config.multiSelect;
            let renderIns;
            if (renderType == 'formSelects') {
                renderObj = formSelects;
                // 渲染下拉选择器组件
                renderIns = formSelects.data(config.selectId, 'server', {
                    url: config.url,
                    keyName: config.titleKey,
                    keyVal: config.valueKey,
                    searchName: config.searchKey,
                    showPage: config.showPage,
                    radio: !config.multiSelect,
                    size: config.size,
                    initValues: config.initValues,
                    zIndex: config.zIndex,
                });
                if(config.disabled){
                    formSelects.disabled(config.selectId);
                }
            } else if (renderType == 'xmSelect') {
                renderObj = xmSelect;
                // 渲染下拉选择器组件
                let select = "#" + config.selectId;
                let formName = $(select).attr("name");
                var renderFunc = function () {
                    return xmSelect.render({
                        ...config,
                        model: {
                            ...config.model,
                            zIndex: config.model.zIndex || config.zIndex,
                        },
                        el: select,
                        name: formName ? formName : select,
                        radio: !config.multiSelect,
                        clickClose: !config.multiSelect,
                        disabled: config.disabled,
                        height: config.height?config.height:'auto',
                        data: config.data ? config.data : [],
                        tree: {
                            ...config.tree,
                            show: true,
                            showFolderIcon: true,
                            showLine: true,
                            indent: 20,
                            expandedKeys: config.tree.expandedKeys,
                            lazy: config.tree.lazy,
                            load: function (item, cb) {
                                let postData = {start: 0, limit: config.tree.size}
                                postData[config.tree.pidFilterParamName] = item.value;
                                $.ajax({
                                    method: 'post',
                                    url: config.url,
                                    async: false,
                                    data: postData,
                                    beforeSend: function () {
                                        console.log('正在加载下级节点列表');
                                    },
                                    dataType: 'json',
                                    success: function (rs) {
                                        if (rs.success) {
                                            if (config.tree.beforeData) {
                                                cb(config.tree.beforeData(rs.data));
                                            } else {
                                                cb(that.list2TreeData(rs.data,
                                                    config.valueKey,
                                                    config.tree.pidKey,
                                                    config.titleKey,
                                                    item.value,
                                                    config.initValues));
                                            }
                                        } else {
                                            layer.msg("加载失败！" + rs.message, {icon: 5});
                                        }
                                    },
                                    error: function (r) {
                                        layer.msg("加载错误！")
                                        console.log("加载节点数据错误!", r);
                                    }
                                });
                            }
                        },
                    });
                }

                // 非懒加载模式
                if (!config.tree.lazy) {
                    let that = this;
                    let postData = {start: 0, limit: config.tree.size};
                    $.ajax({
                        method: 'post',
                        url: config.url,
                        async: false,
                        data: postData,
                        beforeSend: function () {
                            $(select).html("加载中...")
                            console.log('正在加载下级节点列表');
                        },
                        dataType: 'json',
                        success: function (rs) {
                            if (rs.success) {
                                var data = []
                                if (config.tree.beforeData) {
                                    data = config.tree.beforeData(rs.data);
                                } else {
                                    data = that.list2TreeData(rs.data,
                                        config.valueKey,
                                        config.tree.pidKey,
                                        config.titleKey,
                                        undefined,
                                        config.initValues);
                                }
                                config.data = data;
                                $(select).html('');
                                renderIns = renderFunc();
                            } else {
                                layer.msg("加载失败！" + rs.message, {icon: 5});
                                $(select).html("加载失败！")
                            }
                        },
                        error: function (r) {
                            layer.msg("加载数据错误！")
                            $(select).html("加载数据错误！")
                            console.log("加载节点数据错误!", r);
                        }
                    });
                } else {
                    renderIns = renderFunc();
                }
            }

            this.renderIns[config.selectId] = renderIns
            return renderIns;
        }

        /**
         * 列表数据转换为树形结构数据
         *
         * @param list
         * @param idKey
         * @param pidKey
         * @param titleKey
         * @param pId
         * @param defaultSelected
         * @return [{
                    "name": "销售员",
                    "value": -1,
                    "children": [{
                            "name": "张三",
                            "value": 100,
                            "selected": true,
                            "children": []
                        }, {
                            "name": "李四1",
                            "value": 2,
                            "selected": true
                        }
                    ]
                }]
         */
        XSelects.prototype.list2TreeData = function (list, idKey, pidKey, titleKey, pId, selectValues) {
            var newList = [];
            for (var i = 0; i < list.length; i++) {
                let item = list[i];
                if (item[idKey] == item[pidKey])
                    return console.error('第' + i + '条数据的' + idKey + '与' + pidKey + '相同', item);
                if (pId === undefined) pId = this.getPids(list, idKey, pidKey);
                if (this.compareValue(item[pidKey], pId)) {
                    var children = this.list2TreeData(list, idKey, pidKey, titleKey, item[idKey], selectValues);
                    item.children = children;
                    newList.push({
                        ...item,
                        name: item[titleKey],
                        value: item[idKey],
                        selected: selectValues == true ? true : this.compareValue(item[idKey], selectValues),
                    });
                }
            }
            return newList;
        }

        /** 获取变量类型 */
        XSelects.prototype.isClass = function (o) {
            if (o === null) return 'Null';
            if (o === undefined) return 'Undefined';
            return Object.prototype.toString.call(o).slice(8, -1);
        }

        /** 判断比较两个值 */
        XSelects.prototype.compareValue = function (val, values) {
            if (this.isClass(values) === 'Array') {
                for (var i = 0; i < values.length; i++)
                    if (val == values[i]) return true;
            }
            return val == values;
        }

        /** 获取顶级的pId */
        XSelects.prototype.getPids = function (list, idName, pidName) {
            var pids = [];
            for (var i = 0; i < list.length; i++) {
                var hasPid = false;
                for (var j = 0; j < list.length; j++) {
                    if (list[i][pidName] == list[j][idName]) {
                        hasPid = true;
                        break;
                    }
                }
                if (!hasPid) pids.push(list[i][pidName]);
            }
            return pids;
        }

        exports('xSelects', new XSelects());
    }
);